﻿namespace DotNetStar.OpenSDK.WeChat
{
    using Open;
    using System.Threading.Tasks;

    /// <summary>
    /// 微信开放平台 api 扩展。
    /// </summary>
    public static class WeChatOpenExtensions
    {
        /// <summary>
        /// 生成可在微信客户端进行登录授权的 url 链接。
        /// </summary>
        /// <remarks>
        /// 该链接只能通过微信客户端打开。
        /// </remarks>
        /// <param name="weChat">微信开放平台。</param>
        /// <param name="request">生成链接的 api 请求。</param>
        /// <returns>一个可以使用微信登录的 url 地址。</returns>
        /// <exception cref="System.ArgumentNullException">config 不能是 null。</exception>
        public static string GenerateWeChatAuthorizeLink(this WeChatOpenPlatform weChat, WeChatAuthorizeCodeApiRequest request)
        {
            if (request == null)
            {
                throw new System.ArgumentNullException(nameof(request));
            }
            return string.Concat(request.RequestUrl, "?", request.GetArguments().ToString(), "#wechat_redirect");
        }

        /// <summary>
        /// 生成可以再网页端进行微信登录的二维码链接。
        /// </summary>
        /// <param name="weChat">微信开放平台。</param>
        /// <param name="request">OAuth2.0 的配置。</param>
        /// <returns>一个可以使用微信登录的 url 地址。</returns>
        /// <exception cref="System.ArgumentNullException">config 不能是 null。</exception>
        public static string GenerateWeChatQrCodeAuthorizeLink(this WeChatOpenPlatform weChat, WeChatQrCodeAuthorizeCodeApiRequest request)
        {
            if (request == null)
            {
                throw new System.ArgumentNullException(nameof(request));
            }
            return string.Concat(request.RequestUrl, "?", request.GetArguments().ToString(), "#wechat_redirect");
        }

        /// <summary>
        /// 以异步的方式获取微信开放平台的应用的令牌凭据。该方法用于微信每一个应用申请 token 时调用。
        /// </summary>
        /// <param name="weChatMP">微信公众平台的实例。</param>
        /// <param name="request">申请令牌的请求。</param>
        /// <returns>这是一个任务，任务结束后返回 <see cref="ClientAccessTokenResponse"/> 的结果。</returns>
        public static Task<ClientAccessTokenResponse> GetClientAccessTokenAsync(this WeChatOpenPlatform weChatMP, ClientAccessTokenApiRequest request)
            => ApiClient.ExecuteAsync(request);

        /// <summary>
        /// 以异步的方式获取指定配置和授权码的令牌结果。该方法用于微信网页登录后的第二步，用户 code 换取 token。
        /// </summary>
        /// <param name="weChat">微信。</param>
        /// <param name="config">OAuth2.0 配置。</param>
        /// <param name="code">授权码。</param>
        /// <returns>
        /// 这是一个任务，在任务结束后获取响应的结果。
        /// </returns>
        /// <exception cref="System.ArgumentNullException">config 不能是 null。</exception>
        public static Task<WeChatOAuthResponse> GetAccessTokenAsync(this WeChatOpenPlatform weChat, OAuth.OAuthConfig config, string code)
        {
            if (config == null)
            {
                throw new System.ArgumentNullException(nameof(config));
            }

            return ApiClient.ExecuteAsync(new WeChatAccessTokenApiRequest(config, code));
        }

        /// <summary>
        /// 以异步的方式刷新 access token 令牌凭据。
        /// </summary>
        /// <param name="weChat">微信开放平台。</param>
        /// <param name="config">OAuth2.0 配置。</param>
        /// <param name="refreshToken">用于刷新 access token 的 refresh_token 字符串。</param>
        /// <returns>这是一个任务，在任务结束后获取响应的结果。</returns>
        /// <exception cref="System.ArgumentNullException">config 不能是 null。</exception>
        public static Task<WeChatOAuthResponse> RefreshAccessTokenAsync(this WeChatOpenPlatform weChat, OAuth.OAuthConfig config, string refreshToken)
        {
            if (config == null)
            {
                throw new System.ArgumentNullException(nameof(config));
            }

            return ApiClient.ExecuteAsync(new WeChatRefreshTokenApiRequest(config, refreshToken));
        }
    }
}
